#include "Thermo.h"
#include "Physics.h"
#include "Events\CSGD_EventSystem.h"
#include "../SGD Wrappers/CSGD_DirectInput.h"
/*#include "../SGD Wrappers/CSGD_Direct3D.h"*/
#include "AudioManager.h"
#include "ProfileManager.h"
#include "Camera.h"

//objects to send applyheat to
#include "Fan.h"
#include "IceBlock.h"
#include "IceLayer.h"
#include "Water.h"
#include "MetalBox.h"
#include "WoodBox.h"
#include "Generator.h"
#include "Saw.h"

#include "Arm.h"

//temp?
#include "GamePlayState.h"
#include "ThermoObject.h"
#include "EmitterManager.h"

// Constructor
Thermo::Thermo(void)
{
	temperatureValue = 5.0f;
	isFire = true;
	isDisable = false;
	SetIsActive(false);
	arm = nullptr;
	castDist = 100.0f;

	//thermoObj = new ThermoObject(this);

	//ObjectManager::GetInstance()->AddObject(3, thermoObj);
}

// Destructor
Thermo::~Thermo(void)
{
}

void Thermo::Shoot(void)
{
	if(isDisable)
	{
		sparkEmitter->SetActive(true);
	}
	else
	{
		//Play Sound effect
		AudioManager::GetInstance()->playSFX("thermo_shoot");

		sparkEmitter->SetActive(false);
		LinecastInfo castInfo;

		tVector2D tempEmitterPos = iceEmitter->GetPosition();
		if(GetHeading().fY == 0)
		{
			if(GetHeading().fX == 1)
			{
				tempEmitterPos.fX += 10.0f;
				tempEmitterPos.fY += 20.0f;
				directionToCast.fX = -1;
				directionToCast.fY = 0;
			}
			else if(GetHeading().fX == -1)
			{
				tempEmitterPos.fX -= 10.0f;
				tempEmitterPos.fY += 20.0f;
				directionToCast.fX = 1;
				directionToCast.fY = 0;
			}
		}
		else if(GetHeading().fY == 1)
		{
			tempEmitterPos.fY +=10.0f;
			directionToCast.fX = 0;
			directionToCast.fY = -1;
		}
		else if(GetHeading().fY == -1)
		{
			tempEmitterPos.fY -=10.0f;
			directionToCast.fX = 0;
			directionToCast.fY = 1;
		}
		tempEmitterPos.fY -= 5.0f;

		float dist;
		tVector2D directionToCastDiagUP = directionToCast;
		directionToCastDiagUP.fY -= 0.3f;
		tVector2D directionToCastDiagDOWN = directionToCast;
		directionToCastDiagDOWN.fY += 0.3f;

		//ignore the two other tools
		vector<GameObject*> ignoreVector;
		ignoreVector.push_back(GamePlayState::GetInstance()->GetPlayer()->GetToolManager()->GetGrap().GetGrappleObj());
		ignoreVector.push_back(GamePlayState::GetInstance()->GetPlayer()->GetToolManager()->GetMag().GetMagnetObject());
		ignoreVector.push_back(GamePlayState::GetInstance()->GetPlayer());
		
		//Linecast straight towards heading, and with two slight offsets
		if(Physics::LineCast(castInfo,castDist, tempEmitterPos, directionToCast,ignoreVector) || 
			Physics::LineCast(castInfo,castDist, tempEmitterPos, directionToCastDiagUP,ignoreVector) ||
			Physics::LineCast(castInfo,castDist, tempEmitterPos, directionToCastDiagDOWN,ignoreVector))
		{
			int sign = isFire ? +1 : -1;

			if(castInfo.GetObjectHit()->GetObjectID() == "Metal Box")
			{
				MetalBox * box = (MetalBox*)castInfo.GetObjectHit();
				box->ApplyHeat(temperatureValue * sign);
			}
			else if (castInfo.GetObjectHit()->GetObjectID() == "Wood Box")
			{
				WoodBox * box = (WoodBox*)castInfo.GetObjectHit();
				box->ApplyHeat(temperatureValue * sign);
			}
			else if (castInfo.GetObjectHit()->GetObjectID() == "Saw")
			{
				Saw * box = (Saw*)castInfo.GetObjectHit();
				box->ApplyHeat(temperatureValue * sign);
			}
			else if (castInfo.GetObjectHit()->GetObjectID() == "Ice Block")
			{
				IceBlock * ice = (IceBlock*)castInfo.GetObjectHit();
				ice->ApplyHeat(temperatureValue * sign);
			}
			else if (castInfo.GetObjectHit()->GetObjectID() == "Ice Layer")
			{
				IceLayer * ice = (IceLayer*)castInfo.GetObjectHit();
				ice->ApplyHeat(temperatureValue * sign);
			}
			else if(castInfo.GetObjectHit()->GetObjectID() == "Water")
			{
				Water* water = (Water*)castInfo.GetObjectHit();
				water->ApplyHeat(temperatureValue * sign);
			}
			else if (castInfo.GetObjectHit()->GetObjectID() == "Generator")
			{				
				Generator * gen = (Generator*)castInfo.GetObjectHit();
				gen->ApplyHeat(temperatureValue * sign);			
			}
			else if(castInfo.GetObjectHit()->GetObjectID() == "Fan")
			{
				Fan* fan = (Fan*)castInfo.GetObjectHit();
				fan->ApplyHeat(temperatureValue * sign);
			}



			dist = Vector2DLength(castInfo.point - tempEmitterPos);
		}
		else
		{
			tVector2D tempCastPoint; tempCastPoint.fX = tempEmitterPos.fX + 75.0f;
			tempCastPoint.fY = tempEmitterPos.fY + 75.0f;
			dist = Vector2DLength(tempCastPoint - tempEmitterPos);
		}

		emitterPos = tempEmitterPos;
		castDist = dist;
	}

}

void Thermo::Update(float deltaTime)
{
	Player* player = GamePlayState::GetInstance()->GetPlayer();
	//if(isActive)
	//{
	//	if(GetHeading().fY == 0)
	//	{
	//		if(GetHeading().fX == 1)
	//		{
	//			RECT leftRect = {(long)player->GetPosX() - 128, (long)player->GetPosY(), (long)player->GetPosX(), (long)player->GetPosY() +48};
	//			thermoObj->SetHitBox(leftRect);
	//		}
	//		else if(GetHeading().fX == -1)
	//		{
	//			RECT rightRect = {(long)player->GetPosX(), (long)player->GetPosY(), (long)player->GetPosX() + 128, (long)player->GetPosY() +48};
	//			thermoObj->SetHitBox(rightRect);
	//		}
	//	}
	//	else if(GetHeading().fY == 1)
	//	{
	//		RECT upRect = {(long)player->GetPosX(), (long)player->GetPosY()- 128, (long)player->GetPosX() + 48, (long)player->GetPosY()};
	//		thermoObj->SetHitBox(upRect);
	//	}
	//	else if(GetHeading().fY == -1)
	//	{
	//		RECT downRect = {(long)player->GetPosX(), (long)player->GetPosY(), (long)player->GetPosX() + 48, (long)player->GetPosY() + 128};
	//		thermoObj->SetHitBox(downRect);
	//	}
	//}
	//TODO: update this to read Arcade correctly
	if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_LSHIFT) || CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RSHIFT))
	{
		isFire = !isFire;
	}
	if(ProfileManager::GetInstance()->getCurProfile().getControlScheme() == 4 /*XBOX*/)
	{
		if(CSGD_DirectInput::GetInstance()->JoystickButtonPressed(4) || CSGD_DirectInput::GetInstance()->JoystickButtonPressed(5))
			isFire = !isFire;
	}
	else if(ProfileManager::GetInstance()->getCurProfile().getControlScheme() == 5 /*Arcade*/)
	{
		if(CSGD_DirectInput::GetInstance()->JoystickButtonPressed(5))
			isFire = !isFire;
	}

	if(fireEmitter == nullptr)
	{
		fireEmitter = EmitterManager::GetInstance()->GetEmitter("thermo_fire");
	}
	if(iceEmitter == nullptr)
	{
		iceEmitter = EmitterManager::GetInstance()->GetEmitter("thermo_ice");
	}
	if(sparkEmitter == nullptr)
	{
		sparkEmitter = EmitterManager::GetInstance()->GetEmitter("thermo_spark");
	}

	if (isActive)
	{
		EmitterManager::GetInstance()->GetEmitter("thermo_fire")->SetPosX((float)arm->GetToolPointX());
		EmitterManager::GetInstance()->GetEmitter("thermo_fire")->SetPosY((float)arm->GetToolPointY());
		EmitterManager::GetInstance()->GetEmitter("thermo_ice")->SetPosX((float)arm->GetToolPointX());
		EmitterManager::GetInstance()->GetEmitter("thermo_ice")->SetPosY((float)arm->GetToolPointY());
		EmitterManager::GetInstance()->GetEmitter("thermo_spark")->SetPosX((float)arm->GetToolPointX());
		EmitterManager::GetInstance()->GetEmitter("thermo_spark")->SetPosY((float)arm->GetToolPointY()); 
	}

	//Update Emitter heading
	int headingx = (int)GetHeading().fX;
	int headingy = (int)GetHeading().fY;
	if(headingy == 0)
	{
		if(headingx == 1)
		{
			fireEmitter->SetEmitterRotation(270);
			iceEmitter->SetEmitterRotation(270);
			sparkEmitter->SetEmitterRotation(270);
		}
		else if (headingx == -1)
		{
			fireEmitter->SetEmitterRotation(90);
			iceEmitter->SetEmitterRotation(90);
			sparkEmitter->SetEmitterRotation(90);
		}
	}
	else if (headingy == 1)
	{
		fireEmitter->SetEmitterRotation(0);
		iceEmitter->SetEmitterRotation(0);
		sparkEmitter->SetEmitterRotation(0);
	}
	else if (headingy == -1)
	{
		fireEmitter->SetEmitterRotation(180);
		iceEmitter->SetEmitterRotation(180);
		sparkEmitter->SetEmitterRotation(180);
	}

	//Update Emitters
	if(isFire)
	{
		fireEmitter->SetActive(GetActive());
		fireEmitter->Update(deltaTime);
	}
	else
	{
		iceEmitter->SetActive(GetActive());
		iceEmitter->Update(deltaTime);
	}
	if(isDisable)
	{
		sparkEmitter->SetActive(GetActive());
		sparkEmitter->Update(deltaTime);
	}

	if(GetActive())
	{
		if(GamePlayState::GetInstance()->GetPlayer()->GetDeathTimer() <= 0)
			Shoot();
	}
}

void Thermo::Render(void) const
{

	if(GetActive())
	{
		if(GamePlayState::GetInstance()->GetPlayer()->GetDeathTimer() <= 0)
		{
			if(isDisable)
			{
				if(sparkEmitter != nullptr)
				{
					sparkEmitter->Render();
				}
			}
			else if(isFire)
			{
				fireEmitter->Render();
			}
			else
			{
				iceEmitter->Render();
			}
		}
	}

	//tVector2D temp = GetHeading();
	//CSGD_Direct3D::GetInstance()->DrawLine((int)(emitterPos.fX  - Camera::GetInstance()->OffsetX()),
	//	(int)(emitterPos.fY  - Camera::GetInstance()->OffsetY())
	//	,(int)(emitterPos.fX  + directionToCast.fX*castDist - Camera::GetInstance()->OffsetX())
	//	,(int)(emitterPos.fY   + directionToCast.fY*castDist - Camera::GetInstance()->OffsetY()),
	//	D3DCOLOR_ARGB(255,255,20,0),2);
	//CSGD_Direct3D::GetInstance()->DrawLine((int)(emitterPos.fX  - Camera::GetInstance()->OffsetX()),
	//	(int)(emitterPos.fY  - Camera::GetInstance()->OffsetY())
	//	,(int)(emitterPos.fX  + directionToCast2.fX*castDist - Camera::GetInstance()->OffsetX())
	//	,(int)(emitterPos.fY   + directionToCast2.fY*castDist - Camera::GetInstance()->OffsetY()),
	//	D3DCOLOR_ARGB(255,255,20,0),2);
	//RECT pointRect = {(LONG)emitterPos.fX, (LONG)emitterPos.fY, (LONG)emitterPos.fX + 2, (LONG)emitterPos.fY + 2};
	//CSGD_Direct3D::GetInstance()->DrawRect(pointRect, D3DCOLOR_ARGB(255,0,255,0));
}

void Thermo::Disable(void)
{
	isDisable = true;
	//shoot sparks?
}

void Thermo::Enable(void)
{
	isDisable = false;
}

void Thermo::DeactivateTool()
{
	isActive = false;
	RECT none = {0,0,0,0};
	//thermoObj->SetHitBox(none);
}